Recall that the simple linear regression model is:

\[ y_i = \beta_0 + \beta_1 x_i + \epsilon_i \quad \text{for} ~ i=1,\ldots,n, \]

where the error terms \(\epsilon_1,\ldots,\epsilon_n\) are mean zero, independent, and identically distributed random variables.

Let \(\hat{\beta}_1\) denote the parameter estimate of \(\beta_1\). The bias \(\hat{\beta}_1\) in estimating \(\beta_1\) is defined as the expected (i.e., mean) value of \(\hat{\beta}_1 - \beta_1\). A \(100(1-\alpha_1)\)% confidence interval for the slope \(\beta_1\) (assuming independent, normally distributed errors) is \(\hat{\beta}_1 \pm t_{\alpha_1/2,\text{df}} ~ \hat{\sigma}_{\hat{\beta}_1}\), where \(\text{df}\) is the residual (a.k.a., error) degrees of freedom, \(\hat{\sigma}_{\hat{\beta}_1}\) is the standard error of the slope estimate, and \(t_{\alpha_1/2,df}\) is the \(\alpha_1/2\) upper quantile of the \(t\)-distribution with \(\text{df}\) degrees of freedom. The coverage of a confidence interval estimator is the long-run relative frequency that the procedure generates intervals that contain the true value.

The regression coefficients \(\beta_0\) and \(\beta_1\) can be estimated using the method of least-squares. In R, if x and y are numeric vectors of the same length, the least-squares parameter estimates, standard errors, degrees of freedom, etc. are obtained using:

fm <- lm(y ~ x)
fm
summary(fm)

While theory provides results on the bias and coverage in simple linear regression models, the goal is to perform a simulation study to investigate:

The following function conducts such a simulation study. The arguments to the function are:

x <- seq(-2, 2, length = 50)
intercept <- 42
slope <- 3/8
true_y <- intercept + slope * x
error <- rnorm(length(x), sd = .1)
simulated_y <- true_y + error
plot(x, true_y, type = 'l')
points(x, simulated_y)

lm_out <- lm(simulated_y ~ x)
plot(x, true_y, type = 'l')
points(x, simulated_y)
abline(lm_out, col = "red")

slope_simulation <- function(
  regressor,
  intercept,
  slope,
  error_distribution = "normal",
  n_reps,
  alpha1,
  alpha2
) {
  n <- length(regressor) # Number of observations
  z <- (regressor - mean(regressor)) / sd(regressor) # Used for correlated errors
  count_in <- 0
  difference <- numeric(n_reps)
  for (i in 1:n_reps) {
    if (error_distribution == "normal") {
      error <- rnorm(n)
    } else if (error_distribution == "chisq") {
      error <- rchisq(n, 0.5) - 0.5
    } else if (error_distribution == "correlated") {
      error <- rnorm(n, 0.2 * z, 1)
    } else {
      stop("Unknown error distribution")
    }
    
    response <- intercept + slope * regressor + error
    fm <- lm(response ~ regressor)
    
    # Extract slope estimate
    fit_slope <- fm$coefficients[2]
    
    # Calculate difference between slope estimate and slope
    difference[i] <- fit_slope - slope
    
    # Confidence interval on fit_slope
    slope_conf <- fit_slope + c(-1, 1) * qt(1 - alpha1/2, fm$df.residual) * summary(fm)$coefficients[2, "Std. Error"]
    count_in <- count_in + (slope_conf[1] < slope && slope < slope_conf[2])
  }
  
  # Calculate coverage
  coverage <- count_in / n_reps
  
  # Confidence interval on coverage
  coverage_ci <- coverage + c(-1, 1) * qnorm(1 - alpha2/2) * sqrt((coverage  * (1 - coverage))/n_reps)
  
  # Bias estimate
  bias <- mean(difference)
  
  # Confidence interval on bias
  bias_ci <- bias + c(-1, 1) * qnorm(1 - alpha2/2) * sd(difference) / sqrt(n_reps)
  
  # Output
  list(
    coverage = c(
      lower = coverage_ci[1],
      estimate = coverage,
      upper = coverage_ci[2]
    ),
    bias = c(
      lower = bias_ci[1],
      estimate = bias,
      upper = bias_ci[2]
    )
  )
}

For each iteration of the n_reps iterations of the simulation, randomly generate the response (i.e., dependent) vector using the supplied intercept, slope, regressor, and error term distribution. Fit the simple linear regression model and compute a \(100(1-\alpha_1)\)% confidence interval on the slope parameter. Record whether it contains the true slope. Also, record the difference between the slope estimate and its true value.

The proportion of times that the confidence interval contains the true slope is a point estimate of the its coverage. Theory says that the coverage should be \(1-\alpha_1\) when the usual regression assumptions are met. In addition to providing a point estimate of the coverage, you will provide a \(100(1-\alpha_2)\)% confidence interval on the coverage. (Use the normal approximation to the binomial, which is justified by the Central Limit Theorem since nreps is large.)

The average difference between the slope estimate and its true value is a point estimate of the bias. In addition to providing a point estimate of the bias, you will provide a \(100(1-\alpha_2)\)% confidence interval on the bias. (Again, the Central Limit Theorem is applicable.)

The function should return the following six elements:

  1. A point estimate of the bias in estimating the slope
  2. The lower bound of a \(100(1-\alpha_2)\)% confidence interval for the bias
  3. The upper bound of a \(100(1-\alpha_2)\)% confidence interval for the bias
  4. A point estimate of the coverage of the \(100(1-\alpha_1)\)% confidence interval estimator of the slope
  5. The lower bound of a \(100(1-\alpha_2)\)% confidence interval for the coverage
  6. The upper bound of a \(100(1-\alpha_2)\)% confidence interval for the coverage

Evaluate

Consider the following questions:

simulation <- function(
  x, 
  intercept = 3, 
  slope = 2, 
  n_reps = 5000, 
  alpha1 = 0.10, 
  alpha2 = 0.05) {
  for (error_dist in c("normal", "chisq", "correlated")) {
    print(paste("Results for", error_dist, "errors:"))
    results <- slope_simulation(x, intercept, slope, error_dist, n_reps, alpha1, alpha2)
    print(paste0("Bias:     ", results$bias[2], " (", results$bias[1], ", ", results$bias[3], ")"))
    print(paste0("Coverage: ", results$coverage[2], " (", results$coverage[1], ", ", results$coverage[3], ")"))
  }
}

simulation(x = seq(-2, 2, length = 50))
[1] "Results for normal errors:"
[1] "Bias:     -0.00196886706501441 (-0.00535017280794603, 0.0014124386779172)"
[1] "Coverage: 0.8946 (0.886088661926246, 0.903111338073754)"
[1] "Results for chisq errors:"
[1] "Bias:     -8.29872553382316e-05 (-0.00344774648568134, 0.00328177197500487)"
[1] "Coverage: 0.8968 (0.888367608976036, 0.905232391023964)"
[1] "Results for correlated errors:"
[1] "Bias:     0.168531193668325 (0.165160016349742, 0.171902370986907)"
[1] "Coverage: 0.6004 (0.586823239078281, 0.613976760921719)"
simulation(x = seq(-2, 2, length = 5))
[1] "Results for normal errors:"
[1] "Bias:     0.00412424078284751 (-0.0046678589244346, 0.0129163404901296)"
[1] "Coverage: 0.8986 (0.890233086608762, 0.906966913391238)"
[1] "Results for chisq errors:"
[1] "Bias:     -0.00144274261426738 (-0.0102624316043981, 0.0073769463758633)"
[1] "Coverage: 0.9258 (0.918535200551234, 0.933064799448766)"
[1] "Results for correlated errors:"
[1] "Bias:     0.137065716259763 (0.128361676332119, 0.145769756187408)"
[1] "Coverage: 0.8812 (0.87223173250488, 0.89016826749512)"
LS0tCnRpdGxlOiAiU2ltdWxhdGlvbiBTdHVkeSBmb3IgU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBjYWNoZSA9IFRSVUUpCmBgYAoKUmVjYWxsIHRoYXQgdGhlIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCBpczoKCiQkCnlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFxlcHNpbG9uX2kgXHF1YWQgXHRleHR7Zm9yfSB+IGk9MSxcbGRvdHMsbiwKJCQKCndoZXJlIHRoZSBlcnJvciB0ZXJtcyAkXGVwc2lsb25fMSxcbGRvdHMsXGVwc2lsb25fbiQgYXJlIG1lYW4gemVybywgaW5kZXBlbmRlbnQsIAphbmQgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQgcmFuZG9tIHZhcmlhYmxlcy4KCkxldCAkXGhhdHtcYmV0YX1fMSQgZGVub3RlIHRoZSBwYXJhbWV0ZXIgZXN0aW1hdGUgb2YgJFxiZXRhXzEkLiBUaGUgYmlhcwokXGhhdHtcYmV0YX1fMSQgaW4gZXN0aW1hdGluZyAkXGJldGFfMSQgaXMgZGVmaW5lZCBhcyB0aGUgZXhwZWN0ZWQgKGkuZS4sIG1lYW4pCnZhbHVlIG9mICRcaGF0e1xiZXRhfV8xIC0gXGJldGFfMSQuIEEgJDEwMCgxLVxhbHBoYV8xKSQlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yCnRoZSBzbG9wZSAkXGJldGFfMSQgKGFzc3VtaW5nIGluZGVwZW5kZW50LCBub3JtYWxseSBkaXN0cmlidXRlZCBlcnJvcnMpIGlzIAokXGhhdHtcYmV0YX1fMSBccG0gdF97XGFscGhhXzEvMixcdGV4dHtkZn19IH4gXGhhdHtcc2lnbWF9X3tcaGF0e1xiZXRhfV8xfSQsIAp3aGVyZSAkXHRleHR7ZGZ9JCBpcwp0aGUgcmVzaWR1YWwgKGEuay5hLiwgZXJyb3IpIGRlZ3JlZXMgb2YgZnJlZWRvbSwgJFxoYXR7XHNpZ21hfV97XGhhdHtcYmV0YX1fMX0kCmlzIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgc2xvcGUgZXN0aW1hdGUsIGFuZCAkdF97XGFscGhhXzEvMixkZn0kIGlzIHRoZQokXGFscGhhXzEvMiQgdXBwZXIgcXVhbnRpbGUgb2YgdGhlICR0JC1kaXN0cmlidXRpb24gd2l0aCAkXHRleHR7ZGZ9JCBkZWdyZWVzIG9mIGZyZWVkb20uClRoZSBjb3ZlcmFnZSBvZiBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZXN0aW1hdG9yIGlzIHRoZSBsb25nLXJ1biByZWxhdGl2ZQpmcmVxdWVuY3kgdGhhdCB0aGUgcHJvY2VkdXJlIGdlbmVyYXRlcyBpbnRlcnZhbHMgdGhhdCBjb250YWluIHRoZSB0cnVlIHZhbHVlLgoKVGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzICRcYmV0YV8wJCBhbmQgJFxiZXRhXzEkIGNhbiBiZSBlc3RpbWF0ZWQgdXNpbmcgdGhlCm1ldGhvZCBvZiBsZWFzdC1zcXVhcmVzLiBJbiBSLCBpZiB4IGFuZCB5IGFyZSBudW1lcmljIHZlY3RvcnMgb2YgdGhlIHNhbWUKbGVuZ3RoLCB0aGUgbGVhc3Qtc3F1YXJlcyBwYXJhbWV0ZXIgZXN0aW1hdGVzLCBzdGFuZGFyZCBlcnJvcnMsIGRlZ3JlZXMgb2YKZnJlZWRvbSwgZXRjLiBhcmUgb2J0YWluZWQgdXNpbmc6CgpgYGB7ciwgZXZhbD1GQUxTRX0KZm0gPC0gbG0oeSB+IHgpCmZtCnN1bW1hcnkoZm0pCmBgYAoKV2hpbGUgdGhlb3J5IHByb3ZpZGVzIHJlc3VsdHMgb24gdGhlIGJpYXMgYW5kIGNvdmVyYWdlIGluIHNpbXBsZSBsaW5lYXIKcmVncmVzc2lvbiBtb2RlbHMsIHRoZSBnb2FsIGlzIHRvIHBlcmZvcm0gYSBzaW11bGF0aW9uIHN0dWR5IHRvIGludmVzdGlnYXRlOgoKKyBUaGUgYmlhcyBpbiBlc3RpbWF0aW5nIHRoZSBzbG9wZSwgYW5kCisgVGhlIGNvdmVyYWdlIG9mIHRoZSAkMTAwKDEtXGFscGhhXzEpJCUgY29uZmlkZW5jZSBpbnRlcnZhbCBlc3RpbWF0b3IgZm9yIHRoZQpzbG9wZSBiYXNlZCBvbiB0aGUgdXN1YWwgbm9ybWFsaXR5IGFzc3VtcHRpb24uCgpUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIGNvbmR1Y3RzIHN1Y2ggYSBzaW11bGF0aW9uIHN0dWR5LiBUaGUgYXJndW1lbnRzIHRvIHRoZQpmdW5jdGlvbiBhcmU6CgorIGByZWdyZXNzb3JgOiBJbmRlcGVuZGVudCB2YXJpYWJsZSBwYXNzZWQgYXMgYSBudW1lcmljIHZlY3RvciBvZiBhcmJpdHJhcnkKbGVuZ3RoLgorIGBpbnRlcmNlcHRgOiBUcnVlIGludGVyY2VwdCBwYXNzZWQgYXMgYSBudW1lcmljIHZlY3RvciBvZiBsZW5ndGggb25lLgorIGBzbG9wZWA6IFRydWUgc2xvcGUgcGFzc2VkIGFzIGEgbnVtZXJpYyB2ZWN0b3Igb2YgbGVuZ3RoIG9uZS4KKyBgZXJyb3JfZGlzdHJpYnV0aW9uYDogRGlzdHJpYnV0aW9uIG9mIHRoZSBlcnJvciB0ZXJtIHBhc3NlZCBhcyBhIGNoYXJhY3Rlcgp2ZWN0b3Igb2YgbGVuZ3RoIG9uZSwgZXF1YWxpbmcgb25lIG9mOgogICAgKyAibm9ybWFsIjogRXJyb3IgdGVybXMgYXJlIGluZGVwZW5kZW50IGFuZCBzdGFuZGFyZCBub3JtYWxseSBkaXN0cmlidXRlZC4KICAgICsgImNoaXNxIjogRXJyb3IgdGVybSBhcmUgaW5kZXBlbmRlbnRseSBjaGktc3F1YXJlZCBkaXN0cmlidXRlZCB3aXRoIDAuNQogICAgZGVncmVlcyBvZiBmcmVlZG9tIGFuZCBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IDAuNSAoc28gdGhhdCB0aGUgbWVhbiBvZiB0aGUKICAgIGVycm9yIHRlcm0gaXMgemVybykuICBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIHZpb2xhdGluZyB0aGUgbm9ybWFsaXR5CiAgICBhc3N1bXB0aW9uIG9mIHRoZSBlcnJvciB0ZXJtcyAkXGVwc2lsb24kJ3MuCiAgICArICJjb3JyZWxhdGVkIjogRXJyb3IgdGVybSBmb3Igb2JzZXJ2YXRpb24gaSBpcyBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoCiAgICBtZWFuICQwLjIgel9pJCBhbmQgdmFyaWFuY2UgMSwgd2hlcmUgJHpfaSA9ICh4X2ktXGJhcnt4fSkvcyQgaXMgdGhlCiAgICBzdGFuZGFyZGl6ZWQgdmFsdWUgb2YgcmVncmVzc29yIGZvciBvYnNlcnZhdGlvbiBpLiAgVGhpcyBoYXMgdGhlIGVmZmVjdCBvZgogICAgbWFraW5nIHRoZSBlcnJvciB0ZXJtcyAkXGVwc2lsb24kJ3MgY29ycmVsYXRlZCwgdGhlcmVieSB2aW9sYXRpbmcgdGhlCiAgICBpbmRlcGVuZGVuY2UgYXNzdW1wdGlvbi4KKyBgbl9yZXBzYDogTnVtYmVyIG9mIHJlcGxpY2F0aW9ucy4KKyBgYWxwaGExYDogRXF1YWxzIDEuMCBtaW51cyB0aGUgY29uZmlkZW5jZSBjb2VmZmljaWVudCBmb3IgdGhlIGNvbmZpZGVuY2UKaW50ZXJ2YWwgZXN0aW1hdG9yIG9mIHRoZSBzbG9wZS4gRm9yIGV4YW1wbGUsIGZvciA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMgb24KdGhlIHNsb3BlLCBhbHBoYTEgPSAwLjA1LgorIGBhbHBoYTJgOiBFcXVhbHMgMS4wIG1pbnVzIHRoZSBjb25maWRlbmNlIGNvZWZmaWNpZW50IGZvciB0aGUgY29uZmlkZW5jZQppbnRlcnZhbHMgb2YgdGhlIGJpYXMgYW5kIGNvdmVyYWdlIHByb2JhYmlsaXRpZXMuIEZvciBleGFtcGxlLCBmb3IgYSA5MCUKY29uZmlkZW5jZSBpbnRlcnZhbCBvbiB0aGUgYmlhcywgYWxwaGEyID0gMC4xMC4KCmBgYHtyfQp4IDwtIHNlcSgtMiwgMiwgbGVuZ3RoID0gNTApCmludGVyY2VwdCA8LSA0MgpzbG9wZSA8LSAzLzgKdHJ1ZV95IDwtIGludGVyY2VwdCArIHNsb3BlICogeAplcnJvciA8LSBybm9ybShsZW5ndGgoeCksIHNkID0gLjEpCnNpbXVsYXRlZF95IDwtIHRydWVfeSArIGVycm9yCmBgYAoKCmBgYHtyfQpwbG90KHgsIHRydWVfeSwgdHlwZSA9ICdsJykKcG9pbnRzKHgsIHNpbXVsYXRlZF95KQpgYGAKCmBgYHtyfQpsbV9vdXQgPC0gbG0oc2ltdWxhdGVkX3kgfiB4KQpgYGAKCmBgYHtyfQpwbG90KHgsIHRydWVfeSwgdHlwZSA9ICdsJykKcG9pbnRzKHgsIHNpbXVsYXRlZF95KQphYmxpbmUobG1fb3V0LCBjb2wgPSAicmVkIikKYGBgCgoKYGBge3J9CnNsb3BlX3NpbXVsYXRpb24gPC0gZnVuY3Rpb24oCiAgcmVncmVzc29yLAogIGludGVyY2VwdCwKICBzbG9wZSwKICBlcnJvcl9kaXN0cmlidXRpb24gPSAibm9ybWFsIiwKICBuX3JlcHMsCiAgYWxwaGExLAogIGFscGhhMgopIHsKICBuIDwtIGxlbmd0aChyZWdyZXNzb3IpICMgTnVtYmVyIG9mIG9ic2VydmF0aW9ucwogIHogPC0gKHJlZ3Jlc3NvciAtIG1lYW4ocmVncmVzc29yKSkgLyBzZChyZWdyZXNzb3IpICMgVXNlZCBmb3IgY29ycmVsYXRlZCBlcnJvcnMKICBjb3VudF9pbiA8LSAwCiAgZGlmZmVyZW5jZSA8LSBudW1lcmljKG5fcmVwcykKICBmb3IgKGkgaW4gMTpuX3JlcHMpIHsKICAgIGlmIChlcnJvcl9kaXN0cmlidXRpb24gPT0gIm5vcm1hbCIpIHsKICAgICAgZXJyb3IgPC0gcm5vcm0obikKICAgIH0gZWxzZSBpZiAoZXJyb3JfZGlzdHJpYnV0aW9uID09ICJjaGlzcSIpIHsKICAgICAgZXJyb3IgPC0gcmNoaXNxKG4sIDAuNSkgLSAwLjUKICAgIH0gZWxzZSBpZiAoZXJyb3JfZGlzdHJpYnV0aW9uID09ICJjb3JyZWxhdGVkIikgewogICAgICBlcnJvciA8LSBybm9ybShuLCAwLjIgKiB6LCAxKQogICAgfSBlbHNlIHsKICAgICAgc3RvcCgiVW5rbm93biBlcnJvciBkaXN0cmlidXRpb24iKQogICAgfQogICAgCiAgICByZXNwb25zZSA8LSBpbnRlcmNlcHQgKyBzbG9wZSAqIHJlZ3Jlc3NvciArIGVycm9yCiAgICBmbSA8LSBsbShyZXNwb25zZSB+IHJlZ3Jlc3NvcikKICAgIAogICAgIyBFeHRyYWN0IHNsb3BlIGVzdGltYXRlCiAgICBmaXRfc2xvcGUgPC0gZm0kY29lZmZpY2llbnRzWzJdCiAgICAKICAgICMgQ2FsY3VsYXRlIGRpZmZlcmVuY2UgYmV0d2VlbiBzbG9wZSBlc3RpbWF0ZSBhbmQgc2xvcGUKICAgIGRpZmZlcmVuY2VbaV0gPC0gZml0X3Nsb3BlIC0gc2xvcGUKICAgIAogICAgIyBDb25maWRlbmNlIGludGVydmFsIG9uIGZpdF9zbG9wZQogICAgc2xvcGVfY29uZiA8LSBmaXRfc2xvcGUgKyBjKC0xLCAxKSAqIHF0KDEgLSBhbHBoYTEvMiwgZm0kZGYucmVzaWR1YWwpICogc3VtbWFyeShmbSkkY29lZmZpY2llbnRzWzIsICJTdGQuIEVycm9yIl0KICAgIGNvdW50X2luIDwtIGNvdW50X2luICsgKHNsb3BlX2NvbmZbMV0gPCBzbG9wZSAmJiBzbG9wZSA8IHNsb3BlX2NvbmZbMl0pCiAgfQogIAogICMgQ2FsY3VsYXRlIGNvdmVyYWdlCiAgY292ZXJhZ2UgPC0gY291bnRfaW4gLyBuX3JlcHMKICAKICAjIENvbmZpZGVuY2UgaW50ZXJ2YWwgb24gY292ZXJhZ2UKICBjb3ZlcmFnZV9jaSA8LSBjb3ZlcmFnZSArIGMoLTEsIDEpICogcW5vcm0oMSAtIGFscGhhMi8yKSAqIHNxcnQoKGNvdmVyYWdlICAqICgxIC0gY292ZXJhZ2UpKS9uX3JlcHMpCiAgCiAgIyBCaWFzIGVzdGltYXRlCiAgYmlhcyA8LSBtZWFuKGRpZmZlcmVuY2UpCiAgCiAgIyBDb25maWRlbmNlIGludGVydmFsIG9uIGJpYXMKICBiaWFzX2NpIDwtIGJpYXMgKyBjKC0xLCAxKSAqIHFub3JtKDEgLSBhbHBoYTIvMikgKiBzZChkaWZmZXJlbmNlKSAvIHNxcnQobl9yZXBzKQogIAogICMgT3V0cHV0CiAgbGlzdCgKICAgIGNvdmVyYWdlID0gYygKICAgICAgbG93ZXIgPSBjb3ZlcmFnZV9jaVsxXSwKICAgICAgZXN0aW1hdGUgPSBjb3ZlcmFnZSwKICAgICAgdXBwZXIgPSBjb3ZlcmFnZV9jaVsyXQogICAgKSwKICAgIGJpYXMgPSBjKAogICAgICBsb3dlciA9IGJpYXNfY2lbMV0sCiAgICAgIGVzdGltYXRlID0gYmlhcywKICAgICAgdXBwZXIgPSBiaWFzX2NpWzJdCiAgICApCiAgKQp9CmBgYAoKRm9yIGVhY2ggaXRlcmF0aW9uIG9mIHRoZSBgbl9yZXBzYCBpdGVyYXRpb25zIG9mIHRoZSBzaW11bGF0aW9uLCByYW5kb21seQpnZW5lcmF0ZSB0aGUgcmVzcG9uc2UgKGkuZS4sIGRlcGVuZGVudCkgdmVjdG9yIHVzaW5nIHRoZSBzdXBwbGllZCBpbnRlcmNlcHQsCnNsb3BlLCByZWdyZXNzb3IsIGFuZCBlcnJvciB0ZXJtIGRpc3RyaWJ1dGlvbi4gRml0IHRoZSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24KbW9kZWwgYW5kIGNvbXB1dGUgYSAkMTAwKDEtXGFscGhhXzEpJCUgY29uZmlkZW5jZSBpbnRlcnZhbCBvbiB0aGUgc2xvcGUKcGFyYW1ldGVyLiBSZWNvcmQgd2hldGhlciBpdCBjb250YWlucyB0aGUgdHJ1ZSBzbG9wZS4gQWxzbywgcmVjb3JkIHRoZQpkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHNsb3BlIGVzdGltYXRlIGFuZCBpdHMgdHJ1ZSB2YWx1ZS4KClRoZSBwcm9wb3J0aW9uIG9mIHRpbWVzIHRoYXQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgY29udGFpbnMgdGhlIHRydWUgc2xvcGUgaXMKYSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgaXRzIGNvdmVyYWdlLiBUaGVvcnkgc2F5cyB0aGF0IHRoZSBjb3ZlcmFnZSBzaG91bGQgYmUKJDEtXGFscGhhXzEkIHdoZW4gdGhlIHVzdWFsIHJlZ3Jlc3Npb24gYXNzdW1wdGlvbnMgYXJlIG1ldC4gSW4gYWRkaXRpb24gdG8KcHJvdmlkaW5nIGEgcG9pbnQgZXN0aW1hdGUgb2YgdGhlIGNvdmVyYWdlLCB5b3Ugd2lsbCBwcm92aWRlIGEKJDEwMCgxLVxhbHBoYV8yKSQlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb24gdGhlIGNvdmVyYWdlLiAoVXNlIHRoZSBub3JtYWwKYXBwcm94aW1hdGlvbiB0byB0aGUgYmlub21pYWwsIHdoaWNoIGlzIGp1c3RpZmllZCBieSB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtCnNpbmNlIG5yZXBzIGlzIGxhcmdlLikKClRoZSBhdmVyYWdlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc2xvcGUgZXN0aW1hdGUgYW5kIGl0cyB0cnVlIHZhbHVlIGlzIGEgcG9pbnQKZXN0aW1hdGUgb2YgdGhlIGJpYXMuIEluIGFkZGl0aW9uIHRvIHByb3ZpZGluZyBhIHBvaW50IGVzdGltYXRlIG9mIHRoZSBiaWFzLCB5b3UKd2lsbCBwcm92aWRlIGEgJDEwMCgxLVxhbHBoYV8yKSQlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb24gdGhlIGJpYXMuIChBZ2FpbiwgdGhlCkNlbnRyYWwgTGltaXQgVGhlb3JlbSBpcyBhcHBsaWNhYmxlLikKClRoZSBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHRoZSBmb2xsb3dpbmcgc2l4IGVsZW1lbnRzOgoKMS4gQSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgYmlhcyBpbiBlc3RpbWF0aW5nIHRoZSBzbG9wZQoyLiBUaGUgbG93ZXIgYm91bmQgb2YgYSAkMTAwKDEtXGFscGhhXzIpJCUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIGJpYXMKMy4gVGhlIHVwcGVyIGJvdW5kIG9mIGEgJDEwMCgxLVxhbHBoYV8yKSQlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBiaWFzCjQuIEEgcG9pbnQgZXN0aW1hdGUgb2YgdGhlIGNvdmVyYWdlIG9mIHRoZSAkMTAwKDEtXGFscGhhXzEpJCUgY29uZmlkZW5jZQppbnRlcnZhbCBlc3RpbWF0b3Igb2YgdGhlIHNsb3BlCjUuIFRoZSBsb3dlciBib3VuZCBvZiBhICQxMDAoMS1cYWxwaGFfMikkJSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgY292ZXJhZ2UKNi4gVGhlIHVwcGVyIGJvdW5kIG9mIGEgJDEwMCgxLVxhbHBoYV8yKSQlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBjb3ZlcmFnZQoKIyMgRXZhbHVhdGUKQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6CgorIFVuZGVyIHdoYXQgZXJyb3IgdGVybXMgaXMgdGhlIGVzdGltYXRvciBvZiB0aGUgc2xvcGUgYmlhc2VkPworIERvZXMgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZXN0aW1hdG9yIGhhdmUgdGhlIHJpZ2h0IGNvdmVyYWdlIHVuZGVyIHRoZQpub3JtYWxseSBkaXN0cmlidXRlZCBlcnJvciB0ZXJtcz8KKyBXaGF0IGlzIHRoZSBjb3ZlcmFnZSB1bmRlciB0aGUgY2hpLXNxdWFyZWQgZGlzdHJpYnV0ZWQgZXJyb3IgdGVybXM/CisgV2hhdCBpcyB0aGUgY292ZXJhZ2UgdW5kZXIgdGhlIGNvcnJlbGF0ZWQgZXJyb3IgdGVybXM/CisgRm9yIHRoZSBlcnJvciB0ZXJtcyBpbiB3aGljaCB0aGUgY292ZXJhZ2UgaXMgbm90IGNvcnJlY3QsIHVuZGVyIHdoYXQgc2l0dWF0aW9uCmlzIGl0IG5vdGljZWFibGU/IFdoZW4sIGlmIGV2ZXIsIGRvZXMgdGhpcyBjb3ZlcmFnZSBwcm9ibGVtIGdvIGF3YXk/IFdoYXQKcGhlbm9tZW5vbiBtYWtlcyBpdCBnbyBhd2F5PwoKYGBge3J9CnNpbXVsYXRpb24gPC0gZnVuY3Rpb24oCiAgeCwgCiAgaW50ZXJjZXB0ID0gMywgCiAgc2xvcGUgPSAyLCAKICBuX3JlcHMgPSA1MDAwLCAKICBhbHBoYTEgPSAwLjEwLCAKICBhbHBoYTIgPSAwLjA1KSB7CiAgZm9yIChlcnJvcl9kaXN0IGluIGMoIm5vcm1hbCIsICJjaGlzcSIsICJjb3JyZWxhdGVkIikpIHsKICAgIHByaW50KHBhc3RlKCJSZXN1bHRzIGZvciIsIGVycm9yX2Rpc3QsICJlcnJvcnM6IikpCiAgICByZXN1bHRzIDwtIHNsb3BlX3NpbXVsYXRpb24oeCwgaW50ZXJjZXB0LCBzbG9wZSwgZXJyb3JfZGlzdCwgbl9yZXBzLCBhbHBoYTEsIGFscGhhMikKICAgIHByaW50KHBhc3RlMCgiQmlhczogICAgICIsIHJlc3VsdHMkYmlhc1syXSwgIiAoIiwgcmVzdWx0cyRiaWFzWzFdLCAiLCAiLCByZXN1bHRzJGJpYXNbM10sICIpIikpCiAgICBwcmludChwYXN0ZTAoIkNvdmVyYWdlOiAiLCByZXN1bHRzJGNvdmVyYWdlWzJdLCAiICgiLCByZXN1bHRzJGNvdmVyYWdlWzFdLCAiLCAiLCByZXN1bHRzJGNvdmVyYWdlWzNdLCAiKSIpKQogIH0KfQoKc2ltdWxhdGlvbih4ID0gc2VxKC0yLCAyLCBsZW5ndGggPSA1MCkpCmBgYAoKYGBge3J9CnNpbXVsYXRpb24oeCA9IHNlcSgtMiwgMiwgbGVuZ3RoID0gNSkpCmBgYAoKCg==